/* all platform-specific includes and defines go in this file */
#ifndef PLATFORM_H
#define PLATFORM_H

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <setjmp.h>
#include <math.h>
#include <stdbool.h>
#include "interpreter.h"
#include <stdint.h>

/* host platform includes */
#ifdef UNIX_HOST
# include <unistd.h>
#elif defined(WIN32) /*(predefined on MSVC)*/
#else
# error ***** A platform must be explicitly defined! *****
#endif

/* configurable options */
/* select your host type (or do it in the Makefile):
 #define UNIX_HOST
 #define DEBUGGER
 #define USE_READLINE (defined by default for UNIX_HOST)
 */
#define USE_READLINE

#if defined(WIN32) /*(predefined on MSVC)*/
#undef USE_READLINE
#endif

/* undocumented, but probably useful */
#undef DEBUG_HEAP
#undef DEBUG_EXPRESSIONS
#undef FANCY_ERROR_MESSAGES
#undef DEBUG_ARRAY_INITIALIZER
#undef DEBUG_LEXER
#undef DEBUG_VAR_SCOPE





#define INTERACTIVE_PROMPT_START "starting picoc " PICOC_VERSION " (Ctrl+D to exit)\n"
#define INTERACTIVE_PROMPT_STATEMENT "picoc> "
#define INTERACTIVE_PROMPT_LINE "     > "

//extern jmp_buf exitBuf;
class Platform {
public:

    /* exit with a message */
    static void ProgramFail(ParseState *parser, const char *message, ...);

    /* exit with a message, when we're not parsing a program */
    static void ProgramFailNoParser(Interpreter *pc, const char *Message, ...);

    /* like ProgramFail() but gives descriptive error messages for assignment */
    static void AssignFail(ParseState *parser, const char *format,
                    ValueType *Type1, ValueType *Type2, int Num1, int Num2,
                    const char *funcName, int ParamNo);

    /* exit lexing with a message */
    static void LexFail(Interpreter *pc, struct LexState *Lexer, const char *Message, ...);

    /* printf for compiler error reporting */
    static void PlatformPrintf(IOFILE *stream, const char *format, ...);

    static void PlatformVPrintf(IOFILE *stream, const char *format, va_list Args);

    /* make a new temporary name. takes a static buffer of char [7] as a parameter.
     * should be initialized to "XX0000"
     * where XX can be any characters */
    static char *PlatformMakeTempName(Interpreter *pc, char *TempNameBuffer);

    static void PlatformInit(Interpreter *pc);

    static void PlatformCleanup(Interpreter *pc);

    /* get a line of interactive input */
    static char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt);

    /* get a character of interactive input */
    static int PlatformGetCharacter();

    /* write a character to the console */
    static void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *stream);


    /* exit the program */
    static void PlatformExit(Interpreter *pc, int RetVal);

    static void MsvcSetupFunc(Interpreter *pc);

    static void CTest(ParseState *parser, Value *returnValue,
                      Value **param, int numArgs);

    static void CLineNo(ParseState *parser, Value *returnValue,
                        Value **param, int numArgs);

    static void PlatformLibraryInit(Interpreter *pc);
private:
	static void PrintSourceTextErrorLine(IOFILE *stream, const char *fileName,
										 const char *sourceText, int line, int characterPos);

};
#endif /* PLATFORM_H */
